#include "adc.h"

uint16_t ADC1_CH4_VALUE;

void ADC1_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;
    ADC_InitTypeDef ADC_InitStructure;
    // 开启外设时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    // GPIO PA4 : ADC1_CH4
    GPIO_InitStructure.GPIO_Pin = ADC1_CH4;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // ADC模拟输入
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(ADC1_PORT, &GPIO_InitStructure);
    // DMA1-CH1 DMA数据方向(外设->存贮器)
    DMA_DeInit(DMA1_Channel1);
    // ADC_FLAG_EOC: 转换完成时由硬件置1 ,在读取 ADC_DR 后自动清零
    DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_ADDRESS;                 // 外设地址(读取)
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(&ADC1_CH4_VALUE);         // 存贮器地址(存放结果)
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                          // 外设为数据源
    DMA_InitStructure.DMA_BufferSize = 1;                                       // 数据个数
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;            // 外设地址是否递增
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;                    // 存贮器地址是否递增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 外设数据宽度
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;         // 存贮器数据宽度
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                             // 循环模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;                         // 优先级
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                // DMA_memory_to_memory
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);                                //
    DMA_Cmd(DMA1_Channel1, ENABLE);                                             //
    // ADC1 ADC1-CH4
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                  // 独立模式(ADC1|ADC2独立工作)
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;                  // 连续转换
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;                        // 扫描模式
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;              // 转换结果数据右对齐
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 不使用外部触发转换,软件触发即可
    ADC_InitStructure.ADC_NbrOfChannel = 1;                             // 转换通道1个(开启的ADC通道数量)
    ADC_Init(ADC1, &ADC_InitStructure);
    // Rank(1~16) 规则组序列
    ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_28Cycles5); // 采样周期=28.5*(ADCCLK)
    ADC_DMACmd(ADC1, ENABLE);
    ADC_Cmd(ADC1, ENABLE);      // 开启ADC1
    ADC_ResetCalibration(ADC1); // ADC1复位校准
    while (ADC_GetResetCalibrationStatus(ADC1) == SET)
        ;                       // 等待ADC1复位校准完成
    ADC_StartCalibration(ADC1); // 开始校准
    while (ADC_GetCalibrationStatus(ADC1) == SET)
        ;                                   //  等待ADC1校准完成
    ADC_SoftwareStartConvCmd(ADC1, ENABLE); // ADC1 软件触发
}
